package components.plugins
{
	import UIFree.ObjectEvent;
	
	import classes.clt_events;
	
	import components.plugins.speak.clt_paramWindow;
	
	import data.cd_utils;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.net.URLRequest;
	import flash.utils.Timer;
	
	public class clt_speak extends clt_plugin {
		
		private static const DEFAULT_JAW: Array = [0.32, 0.58];
		private var _jaw		: Bitmap;
		private var _back		: Bitmap;
		private var _jawRect	: Rectangle;
		private var _timer		: Timer;
		private var _sound		: Sound;
		private var _sc			: SoundChannel;
		private var _window		: clt_paramWindow;
		
		
		public static const SPEAK: String = 'SPEAK';
		
		
		public function clt_speak(a_clt: clt_clothingBase) {
			super(a_clt);
		}
		
		override protected function initialize():void {
			_timer 	= new Timer(20);
			_timer.addEventListener(TimerEvent.TIMER, doTimer);
			if (clt.resultLayer.display.maskInfo) updateJaw();
		}
		
		override protected function listenEvents():void {
			super.listenEvents();
			workspace.addEventListener(clt_events.UPDATECUTOUT, doUpdateCutout);
			workspace.addEventListener(clt_events.UPDATEWORKSPACE, doUpdateWorkSpace);
			workspace.addEventListener(SPEAK, doSpeak);
			clt.resultLayer.display.addEventListener(clt_events.AFTERREFRESH, doAfterRefresh);
		}

		override protected function removeEvents(): void {
			super.removeEvents();
			workspace.removeEventListener(clt_events.UPDATECUTOUT, doUpdateCutout);
			workspace.removeEventListener(clt_events.UPDATEWORKSPACE, doUpdateWorkSpace);
			workspace.removeEventListener(SPEAK, doSpeak);
			clt.resultLayer.display.removeEventListener(clt_events.AFTERREFRESH, doAfterRefresh);
		}
		
		protected function doUpdateWorkSpace(e: Event): void {
			if (clt.resultLayer.display.maskInfo) updateJaw();
		}
		
		protected function doAfterRefresh(e: Event): void {
			redrawJaw();
		}
		
		protected function redrawJaw(): void {
			if (_jaw && _jawRect) {
				var mat: Matrix = new Matrix();
				mat.translate(-_jawRect.x, -_jawRect.y);
				_jaw.bitmapData.draw(clt.resultLayer.display, mat, null, null);
			}
		} 

		protected function doUpdateCutout(e: Event): void {
			updateJaw();
		}
		
		protected function updateJaw(): void {
			removeJaw();
			_jawRect = calcJaw();
			
			_back = new Bitmap(new BitmapData(_jawRect.width, _jawRect.height, false, 0));
			_back.x = _jawRect.x;
			_back.y = _jawRect.y;
			
			_jaw = new Bitmap(new BitmapData(_jawRect.width, _jawRect.height, false, 0xFFFFFF));
			_jaw.x = _jawRect.x;
			_jaw.y = _jawRect.y;
			
			clt.resultLayer.editor.addChild(_back);
			clt.resultLayer.editor.addChild(_jaw);
			redrawJaw();
		}
		
		protected function removeJaw(): void {
			if (_jaw) {
				_jaw.parent.removeChild(_jaw);
				_jaw.bitmapData.dispose();
				
				_back.parent.removeChild(_back);
				_back.bitmapData.dispose();
			}
		}
		
		protected function calcJaw(): Rectangle {
			var scale	: Number	= clt.resultLayer.display.scaleFromMask();
			var rect	: Rectangle = clt.resultLayer.display.getFaceRect();
			var jaw		: Array		= clt.resultLayer.display.maskInfo.jaw?clt.resultLayer.display.maskInfo.jaw:DEFAULT_JAW;
			var me 		: Array 	= cd_utils.getEars(clt.resultLayer.display.maskInfo);
			var size	: Number 	= (me[1].x - me[0].x) * scale;
			
			rect.width	= size * jaw[0];
			rect.x	+= me[0].x * scale + (size - rect.width) / 2;
			
			rect.top += me[0].y * scale + size * jaw[1];
			return rect;	
		}
		
		protected function doTimer(e: TimerEvent): void {
			if (_jaw) {
				var offset: int = Math.round((_sc.leftPeak + _sc.rightPeak) * _jawRect.width / 8);
				_jaw.y = _jawRect.y + offset;
				_jaw.height = _jawRect.height - offset;
			}
		}
		
		protected function doPlayComplete(e: Event): void {
			_sc.removeEventListener(Event.SOUND_COMPLETE, doPlayComplete);
			_timer.stop();
		}
		
		protected function doSoundLoad(e: Event): void {
			_sc = _sound.play();
			_sc.addEventListener(Event.SOUND_COMPLETE, doPlayComplete);
			_timer.start();			
		}
		
		public function play(url: String): void {
			_sound 	= new Sound();
			_sound.addEventListener(Event.COMPLETE, doSoundLoad);
			_sound.load(new URLRequest(url));//'http://translate.google.ru/translate_tts?ie=UTF-8&q=' + encodeURI(_playText.text) + '&tl=ru&prev=input'));
		}
		
		override public function execute(params:Object): void {
			if (!_window) _window = new clt_paramWindow(clt.topLayer);
			_window.show();
		}
		
		override public function dispose():void {
			removeJaw();
			super.dispose();
		}
		
		private function doSpeak(e: ObjectEvent): void {
			play('http://translate.google.ru/translate_tts?ie=UTF-8&q=' + encodeURI(e.object as String) + '&tl=ru&prev=input');
		}
	}
}